package com.cirnoworks.uhs.client;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.Selector;

import com.cirnoworks.uhs.AddressCache;
import com.cirnoworks.uhs.AddressKey;
import com.cirnoworks.uhs.Link;
import com.cirnoworks.uhs.LinkManager;
import com.cirnoworks.uhs.Protocal;

public class ClientRedirectSublink extends Link {

	long lastUpdateTime;
	SocketAddress serverAddress;
	SocketAddress redirectorAddress;
	SocketAddress clientAddress;
	ClientLink parent;
	byte[] userKey;
	char servicePort;
	ByteBuffer buf = ByteBuffer.allocateDirect(65536);
	final AddressKey clientAddressKey = new AddressKey();

	public ClientRedirectSublink(Selector selector, LinkManager manager,
			ClientLink parent, SocketAddress serverAddress,
			SocketAddress redirectorAddress, SocketAddress clientAddress,
			byte[] userKey, char servicePort) throws IOException {
		super(selector, manager);
		channel.connect(serverAddress);
		this.serverAddress = serverAddress;
		this.parent = parent;
		this.redirectorAddress = redirectorAddress;
		this.clientAddress = clientAddress;
		this.userKey = userKey;
		this.servicePort = servicePort;
		AddressCache.getAddress((InetSocketAddress) clientAddress,
				clientAddressKey);
	}

	public void sendData(Selector selector, ByteBuffer buf)
			throws ClosedChannelException {
		lastUpdateTime = System.currentTimeMillis();
		sendData(selector, serverAddress, buf);
	}

	@Override
	protected void receiveData(Selector selector, SocketAddress from,
			ByteBuffer buf) throws IOException {
		lastUpdateTime = System.currentTimeMillis();
		this.buf.clear();
		this.buf.put((byte) Protocal.RedirectPayload.OP);
		this.buf.put(userKey);
		this.buf.putChar(servicePort);
		this.buf.putLong(clientAddressKey.getAddress());
		this.buf.putChar((char) clientAddressKey.getPort());
		this.buf.put(buf);
		this.buf.flip();
		parent.sendData(selector, redirectorAddress, this.buf);
	}

	public boolean isTimeout() {
		return System.currentTimeMillis() - lastUpdateTime > 300000;
	}

	@Override
	public void onClose() {
		// TODO Auto-generated method stub

	}

}
